package com.jetwinner.webfast.kernel.service.impl;

import com.jetwinner.toolbag.FileToolkit;
import com.jetwinner.util.*;
import com.jetwinner.webfast.kernel.AppUser;
import com.jetwinner.webfast.kernel.FastAppConst;
import com.jetwinner.webfast.kernel.exception.RuntimeGoingException;
import com.jetwinner.webfast.kernel.service.AppFileService;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author xulixin
 */
@Service
public class AppFileServiceImpl implements AppFileService {

    private final FastAppConst appConst;

    public AppFileServiceImpl(FastAppConst appConst) {
        this.appConst = appConst;
    }


    @Override
    public void addFileGroup(Map<String, Object> fileMap) {

    }

    @Override
    public Map<String, Object> uploadFile(String groupCode, File file) {
        boolean errors = FileToolkit.validateFileExtension(StringUtils.getFilenameExtension(file.getPath()));
        if (errors) {
            throw new RuntimeGoingException("该文件格式，不允许上传。");
        }
        // Map<String, Object> group = groupDao.findGroupByCode(groupCode);
        Map<String, Object> group = FastHashMap.build(1).add("code", groupCode).toMap();
        AppUser user = new AppUser();
        Map<String, Object> record = FastHashMap.build().toMap();
        record.put("userId", user.getId());
        // record.put("groupId", group.get("id"));
        // @todo fix it.
        record.put("mime", "");
        // record.put("mime", file.getMimeType());
        record.put("size", file.getTotalSpace());
        record.put("uri", this.generateUri(group, file));
        record.put("createdTime", System.currentTimeMillis());
        // record = fileDao.addFile(record);
        record.put("file", this.saveFile(file, String.valueOf(record.get("uri"))));

        return record;
    }

    private String generateUri (Map<String, Object> group, File file) {
        String ext = StringUtils.getFilenameExtension(file.getPath());
        if (EasyStringUtil.isBlank(ext)) {
            throw new RuntimeGoingException("获取文件扩展名失败！");
        }

        StringBuilder uri = new StringBuilder();
        group.put("public", "public");
        uri.append(EasyStringUtil.isBlank(group.get("public")) ? "private://" : "public://")
                .append(group.get("code")).append("/");
        uri.append(EasyDateUtil.today("yyyy/MM-dd/HHmmss"));
        uri.append(PhpStringUtil.substring(UUIDUtil.uniqid(), -6))
                .append(PhpStringUtil.substring(UUIDUtil.uniqid("", true), -6));
        uri.append(".").append(ext);
        return uri.toString();
    }

    public Map<String, String> parseFileUri(String uri) {
        Map<String, String> parsed = new HashMap<>(5);
        String[] parts = uri.split("\\://");
        if (parts == null || parts.length != 2) {
            throw new RuntimeGoingException(String.format("解析文件URI(%s)失败！", uri));
        }
        parsed.put("access", parts[0]);
        parsed.put("path", parts[1]);
        parsed.put("directory", PhpStringUtil.getDirectory(parsed.get("path")));
        parsed.put("name", PhpStringUtil.basename(parsed.get("path")));

        String directory;

        if ("public".equals(parsed.get("access"))) {
            directory = appConst.getUploadPublicDirectory();
        } else {
            directory = appConst.getUploadPrivateDirectory();
        }
        parsed.put("fullpath", directory + "/" + parsed.get("path"));
        return parsed;
    }

    private String saveFile(File file, String uri) {
        Map<String, String> parsed = this.parseFileUri(uri);
        String directory;
        if ("public".equalsIgnoreCase(parsed.get("access"))) {
            directory = appConst.getUploadPublicDirectory();
        } else {
            directory = appConst.getUploadPrivateDirectory();
        }

        directory = directory +  "/" + parsed.get("directory");
        File targetDir = new File(directory);
        if (!targetDir.exists()) {
            targetDir.mkdirs();
        }
        File destFile = new File(directory, parsed.get("name"));
        try {
            FileCopyUtils.copy(file, destFile);
        } catch (IOException e) {
            throw new RuntimeGoingException(String.format("文件%s移动失败。", parsed.get("name")));
        }
        return destFile.getPath();
    }
}
